//////////////////////////////////////////////////////////////////////////////
//	$File: $
//	$Revision: $
//	$Author: $
//	$DateTime: $
//	First Author: buggy


#include	<stdio.h>
#include	<string.h>

#include	<QCommandLineParser>
#include	<QDebug>
#include	<QApplication>

#include	"tidyphotoconfig.h"


//////////////////////////////////////////////////////////////////////
//	Tidy Photo Command Line Argument
TidyPhotoArgParser::Def	TidyPhotoArgParser::_def[TPARG_MAX]	=
{
	//	TPARG_NONE
	{	NULL,	NULL,	NULL,	NULL,	NULL	},
	//	TPARG_APP
	{	"a",	"app",	"gui or cmd",	NULL
		,	"Force application mode. If no argument, run GUI mode. Otherwise, run CMD mode."	},
	//	TPARG_MOVE
	{	"m",	"move",	"y or n",	"n"
			, "move(Y) or copy(N) files. Default value is N (copy)."		},
	//	TPARG_SRC
	{	"s",	"src",	"path",	NULL,	"Source <path>."	},
	//	TPARG_DST
	{	"d",	"dst",	"path",	NULL,	"Destination <path>."	},
};


TidyPhotoArgParser::TidyPhotoArgParser()
{
	_helpText	= "";

	_parser	= new QCommandLineParser();

	//_parser->setApplicationDescription("[desc]");
	_parser->addHelpOption();
	_parser->addVersionOption();

	memset(_option, 0, sizeof(_option));
	for (int i = 0; i < TPARG_MAX; ++i)
	{
		if (_def[i].shortName && _def[i].longName)
			_option[i]	= new QCommandLineOption(QStringList() << _def[i].shortName << _def[i].longName, _def[i].desc);
		else if (_def[i].shortName)
			_option[i]	= new QCommandLineOption(_def[i].shortName, _def[i].desc);
		else if (_def[i].longName)
			_option[i]	= new QCommandLineOption(_def[i].longName, _def[i].desc);
		else
			continue;

		if (_def[i].valueName)
			_option[i]->setValueName(_def[i].valueName);
		if (_def[i].valueDefault)
			_option[i]->setDefaultValue(_def[i].valueDefault);

		_parser->addOption(*_option[i]);
	}
}

TidyPhotoArgParser::~TidyPhotoArgParser()
{
	for (int i = 0; i < TPARG_MAX; ++i)
		if (_option[i])
			delete _option[i];
	if (_parser)
		delete _parser;
}

bool TidyPhotoArgParser::Parse(int argc, char* argv[])
{
	QCoreApplication	app(argc, argv);

	app.setApplicationName("tidyphoto");
	app.setApplicationVersion("0.0.0.1");

	_helpText	= "\n";
	_helpText	+= QCoreApplication::applicationName();
	_helpText	+= " ";
	_helpText	+= QCoreApplication::applicationVersion();
	_helpText	+= "\n\n";
	_helpText	+= _parser->helpText().toLocal8Bit().data();
	_helpText	+= "\n\n";

	//_parser->process(app);

	if (!_parser->parse(app.arguments()))
	{
		//	write Error
		fprintf(stderr, "%s\n", _parser->errorText().toLocal8Bit().data());

		WriteHelp();
		return false;
	}
	if (_parser->isSet("help"))
	{
		WriteHelp();
		return false;
	}
	if (_parser->isSet("version"))
	{
		//	write version info
		fprintf(stderr, "%s %s\n\n"
			, QCoreApplication::applicationName().toLocal8Bit().data()
			, QCoreApplication::applicationVersion().toLocal8Bit().data());
		return false;
	}

	return true;
}


void TidyPhotoArgParser::WriteHelp()
{
	fprintf(stderr, "%s", _helpText.toLocal8Bit().data());
}


//////////////////////////////////////////////////////////////////////
//	Tidy Photo Config
#define	TPARG_OPT(n)			TidyPhotoArgParser::n
#define	TPARG_OPTPTR(p, n)		((p)._option[TPARG_OPT(n)])

#define	TPARG_IsSet(p, n)		(p)._parser->isSet( *(TPARG_OPTPTR(p, n)) )
#define	TPARG_Value(p, n)		( (p)._parser->value( *(TPARG_OPTPTR(p, n)) ) )
#define	TPARG_OptName(p, n)		(TPARG_OPTPTR(p, n)->names().size() == 1 ? \
									(TPARG_OPTPTR(p, n)->names().at(0)) : \
									(TPARG_OPTPTR(p, n)->names().at(1)))

#define	TPARG_ERR(p)			{	p.WriteHelp();	delete config;	return NULL;	}
#define	TPARG_ErrorValue(p, n)	{	fprintf(stderr, "\nInvalid value '%s' of option '%s'\n" \
										, TPARG_Value(p, n).toLocal8Bit().data() \
										, TPARG_OptName(p, n).toLocal8Bit().data()); \
									TPARG_ERR(p);	}

TidyPhotoConfig* TidyPhotoConfig::ParseCommandLine(int argc, char* argv[])
{
	TidyPhotoArgParser	argParser;

	if (!argParser.Parse(argc, argv))
		return NULL;


	TidyPhotoConfig*	config	= new TidyPhotoConfig();

	if (1 < argc)
		config->_isGui	= false;
	else
		config->_isGui	= true;


	if (TPARG_IsSet(argParser, TPARG_APP))
	{
		QString	value	= TPARG_Value(argParser, TPARG_APP);

		if (0 == QString::compare(value, "gui", Qt::CaseInsensitive))
			config->SetGui(true);
		else if (0 == QString::compare(value, "cmd", Qt::CaseInsensitive))
			config->SetGui(false);
		else
			TPARG_ErrorValue(argParser, TPARG_APP);
	}

	if (TPARG_IsSet(argParser, TPARG_MOVE))
	{
		QString	value	= TPARG_Value(argParser, TPARG_MOVE);

		if (0 == QString::compare(value, "y", Qt::CaseInsensitive)
				|| 0 == QString::compare(value, "yes", Qt::CaseInsensitive))
			config->SetMoveFiles(true);
		else if (0 == QString::compare(value, "n", Qt::CaseInsensitive)
				|| 0 == QString::compare(value, "no", Qt::CaseInsensitive))
			config->SetMoveFiles(false);
		else
			TPARG_ErrorValue(argParser, TPARG_MOVE);
	}


	config->SetSourcePath( TPARG_Value(argParser, TPARG_SRC).toLocal8Bit().data() );
	config->SetDestPath( TPARG_Value(argParser, TPARG_DST).toLocal8Bit().data() );

	if (false == config->_isGui)
	{
		if (NULL == config->SourcePath())
		{
			fprintf(stderr, "\nMissing source path in console application.\n");
			TPARG_ERR(argParser);
		}
			
		if (NULL == config->DestPath())
		{
			fprintf(stderr, "\nMissing destination path in console application.\n");
			TPARG_ERR(argParser);
		}
	}
	

	return config;
}

//////////////////////////////////////////////////////////////////////
//	Tidy Photo Config
TidyPhotoConfig::TidyPhotoConfig()
	:	_isGui(true)
	,	_moveFiles(false)
	,	_srcPath(NULL)
	,	_dstPath(NULL)
{
}

TidyPhotoConfig::~TidyPhotoConfig()
{
	if (_srcPath)
		delete _srcPath;
	if (_dstPath)
		delete _dstPath;
}

void TidyPhotoConfig::SetSourcePath(const char* srcPath)
{
	if (_srcPath)
	{
		delete _srcPath;
		_srcPath	= NULL;
	}

	if (srcPath && strlen(srcPath) > 0)
	{
		_srcPath	= new char[strlen(srcPath) + 1];
		strcpy(_srcPath, srcPath);
	}
}

void TidyPhotoConfig::SetDestPath(const char* dstPath)
{
	if (_dstPath)
	{
		delete _dstPath;
		_dstPath	= NULL;
	}

	if (dstPath && strlen(dstPath) > 0)
	{
		_dstPath	= new char[strlen(dstPath) + 1];
		strcpy(_dstPath, dstPath);
	}
}



void TidyPhotoConfig::Dump()
{
	qDebug("CONFIG:");
	qDebug("application: %s", IsGui() ? "GUI" : "CONSOLE");
	qDebug("move files : %s", IsMoveFiles() ? "move" : "copy");
	qDebug("src path   : %s", SourcePath() ? SourcePath() : "<NOT SET>");
	qDebug("dst path   : %s", DestPath() ? DestPath() : "<NOT SET>");
}

